package cn.jnetty.ioc.definition;

import cn.jnetty.api.annotation.*;
import cn.jnetty.api.exception.JnettyIocException;
import cn.jnetty.api.executors.JExecutors;
import cn.jnetty.api.handler.RouterHandler;
import cn.jnetty.api.handler.ParameterHandler;
import cn.jnetty.api.interceptor.HandlerInterceptor;
import cn.jnetty.ioc.mapping.JRequestDefinitionBean;
import cn.jnetty.ioc.mapping.JRequestDefinitionBeanFactory;
import cn.jnetty.ioc.method.BytesRouterHandlerImpl;
import cn.jnetty.ioc.method.DefaultBytesParameterHandler;
import cn.jnetty.ioc.method.DefaultExecutors;
import cn.jnetty.ioc.method.DefaultHandlerInterceptor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @author 猪哥亮
 * @email 1030681978@qq.com
 * @date 2020/4/6 18:46
 * 描述：
 */
public class JRequestMappingBeanDefinition extends JDefaultBeanDefinition {
    public JRequestMappingBeanDefinition(JRequestMapping component, Class<?> clazz) {
        super(component, clazz);
        init();
    }

    @Override
    protected void init() {
        try {
            Object o = clazz.newInstance();
            JDefaultBeanDefinitionFactory.getInstance().put(null, clazz, o);
            mapping(o);
            //装配这个对象
            JDefaultBeanDefinition.autowired(o);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void mapping(Object o) {
        Method[] methods = clazz.getDeclaredMethods();
        Class c = clazz.getSuperclass();
        while (c != Object.class) {
            int srcLength = methods.length;
            Method[] superFields = c.getDeclaredMethods();
            methods = Arrays.copyOf(methods, methods.length + superFields.length);
            System.arraycopy(superFields, 0, methods, srcLength, superFields.length);
            c = c.getSuperclass();
        }
        for (Method method : methods) {
            Annotation[] annotations = method.getAnnotations();
            for (Annotation annotation : annotations) {
                Class<? extends Annotation> annotationType = annotation.annotationType();
                JRequestDefinitionBean bean = null;
                if (annotationType == JTcpMapping.class) {
                    JTcpMapping mapping = JTcpMapping.class.cast(annotation);
                    bean = new JRequestDefinitionBean(o, mapping.path(), method);
                } else if (annotationType == JUdpMapping.class) {
                    JUdpMapping mapping = JUdpMapping.class.cast(annotation);
                    bean = new JRequestDefinitionBean(o, mapping.path(), method);
                } else if (annotationType == JWebsocketMapping.class) {
                    JWebsocketMapping mapping = JWebsocketMapping.class.cast(annotation);
                    bean = new JRequestDefinitionBean(o, mapping.path(), method);
                } else if (annotationType == JGetMapping.class) {
                    JGetMapping mapping = JGetMapping.class.cast(annotation);
                    bean = new JRequestDefinitionBean(o, mapping.path(), method);
                } else if (annotationType == JPostMapping.class) {
                    JPostMapping mapping = JPostMapping.class.cast(annotation);
                    bean = new JRequestDefinitionBean(o, mapping.path(), method);
                }
                //其他的生命周期方法
                autowiredDefaultMappingConfiguration(bean);
            }
        }
    }

    /**
     * 注入默认配置
     *
     * @param bean
     */
    private void autowiredDefaultMappingConfiguration(JRequestDefinitionBean bean) {
        if (bean == null) {
            return;
        }
        JRequestMapping requestMapping = (JRequestMapping) annotation;
        if (requestMapping.value() != null && requestMapping.value() != "") {
            String path = requestMapping.value() + "/" + bean.getPath();
            bean.setPath(path);
        } else {
            bean.setPath("/" + bean.getPath());
        }
        log.debug("路由装配++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[{}]", bean.getPath());
        RouterHandler resolver = ((RouterHandler) getByList(RouterHandler.class, new BytesRouterHandlerImpl())).instance();
        ParameterHandler parameterHandler = (ParameterHandler) getByList(ParameterHandler.class, new DefaultBytesParameterHandler());
        HandlerInterceptor handlerInterceptor = (HandlerInterceptor) getByList(HandlerInterceptor.class, new DefaultHandlerInterceptor());
        JExecutors jExecutors = (JExecutors) getByList(JExecutors.class, new DefaultExecutors());
        resolver.setHandlerInterceptor(handlerInterceptor);
        resolver.setJRequestDefinitionBean(bean);
        resolver.setParameterHandler(parameterHandler);
        resolver.setJExcutors(jExecutors);
        JRequestDefinitionBeanFactory.getInstance().put(bean, resolver);
    }

    private Object getByList(Class<?> clazz, Object defaultObj) {
        List<Object> objs = JDefaultBeanDefinitionFactory.getInstance().getListByType(clazz);
        if (objs.size() > 1) {
            throw new RuntimeException("RouterHandler.class 找到多个对象,不知道要注入哪一个");
        }
        if(objs.size() == 0){
            JDefaultBeanDefinitionFactory.getInstance().put(null, RouterHandler.class, defaultObj);
            return defaultObj;
        }
        return objs.get(0);
    }
}
